package socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
 * 聊天室服务端:将服务端听的过程定义在了线程里，并在start方法里启用线程
 *
 * @author XingHaiYang
 * @date 2022/9/15 14:05
 */
public class Server2 {
    /**
     * 定义ss对象
     */
    private ServerSocket serverSocket;

    /**
     * 服务端的构造器，申请端口号，并监听端口号
     */
    public Server2() {
        try {
            System.out.println("服务端正在启动...");
            serverSocket = new ServerSocket(8088);
            System.out.println("服务端启动成功！");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过ss的accept方法得到s,然后把s传给自定义的线程
     */
    public void start() {
        try {
            System.out.println("等待客户端连接...");
            Socket s = serverSocket.accept();
            System.out.println("一个客户端连接成功！");
            //启动一个线程来处理与该客户端的交互
            Runnable r = new ClientHandler(s);
            Thread t = new Thread(r);
            t.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 程序的入口，申请端口号，监听端口号，并调用start方法，从而执行线程里定义的交互任务
     * @param args
     */
    public static void main(String[] args) {
        Server2 s2 = new Server2();
        s2.start();
    }

    /**
     * 内部类：作用是创建一个内部类，主要是定义一个线程，来执行与客户端的交互
     */
    private class ClientHandler implements Runnable{
        /**
         * 定义Socket对象和host地址
         */
        private Socket s;

        /**
         *  内部类的构造器，给s属性赋值
         */
        public ClientHandler(Socket s) {
            this.s = s;
        }

        /**
         * 重写Runnable接口中的run方法，定义线程要执行的任务(定义的什么任务：服务端与客户端交互的任务)
         */
        @Override
        public void run() {
            try {
                InputStream in = s.getInputStream();
                InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8);
                BufferedReader br = new BufferedReader(isr);
                String listen;
                while((listen = br.readLine()) != null){
                    System.out.println("客户端说："+listen);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
